沪胶量化跟踪框架

数据一览

In [1]:
# 导入所需模块
import sys
sys.path.append("..")
from baseset import *
from getdata import getdata
import hcplot as hc
import pandas as pd

# 获取数据
fpath ='./data/w_datadic_ru.xlsx'
df = getdata(fpath,startdate='2005-01-01')

# 加工数据
df['Wind橡胶指数(月均)'] = df['Wind橡胶指数'].resample('M').mean()
df['上期所天胶库存'] = round(df['上期所天胶库存'] / 10000, 2)
df['期现价差'] = df['Wind橡胶指数'] - df['云南全乳胶(上海)']
df['重卡销量'] = df['重型货车销量'] + df['半挂牵引车销量'] + df['非完整车辆销量']
df['月度供需差:中国'] = df['天胶产量:中国'] + df['天胶进口:中国'] - df['天胶消费:中国']

df0 = (df.tail(10)).T.fillna('')
df0.columns = (df0.columns.map(lambda t: t.strftime('%Y-%m-%d')))
df0
Welcome to use Wind Quant API for Python (WindPy)!

COPYRIGHT (C) 2017 WIND INFORMATION CO., LTD. ALL RIGHTS RESERVED.
IN NO CIRCUMSTANCE SHALL WIND BE RESPONSIBLE FOR ANY DAMAGES OR LOSSES CAUSED BY USING WIND QUANT API FOR Python.
Out[1]:
2018-05-31 2018-06-01 2018-06-04 2018-06-05 2018-06-06 2018-06-07 2018-06-08 2018-06-11 2018-06-12 2018-06-13
Wind橡胶指数 12132.98 12135.19 12153.51 12052.89 12069.43 12137.88 11846.83 11838.65 11843.81 11253.11
Wind商品指数 1081.99 1087.51 1082.19 1079.42 1081.97 1088.08 1076.07 1081.75 1092.12 1090.87
美元指数 93.99 94.20 94.02 93.87 93.64 93.44 93.55 93.58 93.83 93.57
美元兑人民币(中间价) 6.40 6.42 6.41 6.40 6.40 6.39 6.41 6.40 6.40 6.41
沪深300 3802.38 3770.59 3807.58 3845.32 3837.35 3831.01 3779.62 3779.98 3825.95 3788.34
道琼斯工业指数 24415.84 24635.21 24813.69 24799.98 25146.39 25241.41 25316.53 25322.31 25320.73 25201.20
布油 77.61 76.71 75.37 74.96 75.86 77.44 76.34 76.36 75.43 76.56
沪胶(活跃合约收盘) 11670.00 11680.00 11695.00 11605.00 11620.00 11685.00 11415.00 11400.00 11400.00 10835.00
日胶(活跃合约收盘) 190.90 189.40 190.40 187.20 188.10 189.70 186.10 184.90 186.50 181.30
云南全乳胶(上海) 11000.00 11000.00 11000.00 10900.00 10850.00 11000.00 10750.00 10750.00 10700.00 10300.00
顺丁橡胶(中石化华北) 12720.00 12720.00 12720.00 12420.00 12420.00 12420.00 12420.00 12120.00 12120.00 11620.00
丁苯橡胶(中石化华北) 13100.00 13100.00 13100.00 12800.00 12800.00 12800.00 12800.00 12500.00 12500.00 12000.00
丁二烯(中石化华北) 12000.00 12000.00 12000.00 12000.00 12000.00 12000.00 12000.00 12000.00 12000.00 11300.00
沪胶1月 13760.00 13760.00 13780.00 13695.00 13705.00 13770.00 13500.00 13480.00 13470.00 12685.00
沪胶5月 14045.00 14050.00 14075.00 13980.00 14010.00 14060.00 13835.00 13795.00 13770.00 12990.00
沪胶9月 11670.00 11680.00 11695.00 11605.00 11620.00 11685.00 11415.00 11400.00 11400.00 10835.00
沪胶11月 11850.00 11850.00 11880.00 11770.00 11790.00 11855.00 11585.00 11565.00 11545.00 10990.00
青岛保税区橡胶库存 17.52
上期所天胶库存 44.56 44.58 44.62 44.61 44.60 44.74 44.82 45.03 45.05 45.20
全钢胎开工率 77.62 71.60
半钢胎开工率 74.11 65.92
汽车销量 2288000.00
重型货车销量
半挂牵引车销量 39000.00
非完整车辆销量
天胶产量:中国
天胶进口:中国
天胶消费:中国
天胶产量:泰国
天胶产量:印尼
天胶产量:马来西亚
天胶产量:印度
天胶产量:越南
天胶产量:ANRPC
天胶出口:泰国
天胶出口:印尼
天胶出口:马来西亚
天胶出口:越南
天胶出口:ANRPC
中化国际 7.63 7.57 7.57 7.72 7.80 7.67 7.50 7.33 7.47 7.32
海南橡胶 6.62 6.62 6.62 6.62 6.62 6.62 6.62 6.62 6.62 6.62
Wind橡胶指数(月均) 12091.24
期现价差 1132.98 1135.19 1153.51 1152.89 1219.43 1137.88 1096.83 1088.65 1143.81 953.11
重卡销量
月度供需差:中国

多空信号

In [22]:
# 量化评分
q_df = pd.DataFrame()    
q_df['沪胶'] = df['Wind橡胶指数']
q_df['商品'] = df['Wind商品指数']
q_df['美指'] = df['美元指数']
q_df['替代品'] = df['顺丁橡胶(中石化华北)']
q_df['日胶'] = df['日胶(活跃合约收盘)']
q_df['库存'] = df['青岛保税区橡胶库存'].fillna(method='ffill')
# q_df['重卡'] = df['重卡销量']
# q_df['期现差'] = df['期现价差']

q_df = q_df.dropna()

q_df['沪胶_MA'] = pd.rolling_mean(q_df['沪胶'], 60) 
q_df['商品_MA'] = pd.rolling_mean(q_df['商品'], 60) 
q_df['美指_MA'] = pd.rolling_mean(q_df['美指'], 60)
q_df['替代品_MA'] = pd.rolling_mean(q_df['替代品'], 60)
q_df['日胶_MA'] = pd.rolling_mean(q_df['日胶'], 60)
q_df['库存变化'] = q_df['库存'] - q_df['库存'].shift(12)

# 设置各指标权重
q_df['商品_得分'] = 0
q_df.loc[q_df.商品 > q_df.商品_MA,'商品_得分'] = 0.2
q_df.loc[q_df.商品 < q_df.商品_MA,'商品_得分'] = -0.2

q_df['美指_得分'] = 0
q_df.loc[q_df.美指 > q_df.美指_MA,'美指_得分'] = -0.2
q_df.loc[q_df.美指 < q_df.美指_MA,'美指_得分'] = 0.2

q_df['替代品_得分'] = 0
q_df.loc[q_df.替代品 > q_df.替代品_MA,'替代品_得分'] = 0.2
q_df.loc[q_df.替代品 < q_df.替代品_MA,'替代品_得分'] = -0.2

q_df['日胶_得分'] = 0
q_df.loc[q_df.日胶 > q_df.日胶_MA,'日胶_得分'] = 0.2
q_df.loc[q_df.日胶 < q_df.日胶_MA,'日胶_得分'] = -0.2

q_df['库存_得分'] = None
q_df.loc[q_df.库存变化 > 0,'库存_得分'] = -0.2
q_df.loc[q_df.库存变化 < 0,'库存_得分'] = 0.2
q_df['库存_得分'] = q_df['库存_得分'].fillna(method='ffill')

# 周期得分规则:3-8月偏空,9-2偏多
q_df['周期_得分'] = 0.2
q_df.loc[q_df.index.map(lambda t: t.month in [3,4,5,6,7,8]),'周期_得分'] = -0.2

q_df['多空信号'] = q_df['商品_得分'] + q_df['美指_得分'] + q_df['日胶_得分'] + q_df['替代品_得分'] + q_df['库存_得分']

q_df.iloc[:,[0,12,13,14,15,16,17,18]].tail()
hc.y2(q_df[['沪胶','多空信号']],y2list=[1],ldic={1:'column'})
# q_df.index = (q_df.index.map(lambda t: t.strftime('%Y-%m-%d')))
# q_df.to_excel("./data/q_zc.xlsx")  # 输出到excel文件
Out[22]:
沪胶 商品_得分 美指_得分 替代品_得分 日胶_得分 库存_得分 周期_得分 多空信号
2018-06-07 12137.88 0.20 -0.20 0.20 0.20 -0.20 -0.20 0.20
2018-06-08 11846.83 0.20 -0.20 0.20 -0.20 -0.20 -0.20 -0.20
2018-06-11 11838.65 0.20 -0.20 -0.20 -0.20 -0.20 -0.20 -0.60
2018-06-12 11843.81 0.20 -0.20 -0.20 -0.20 -0.20 -0.20 -0.60
2018-06-13 11253.11 0.20 -0.20 -0.20 -0.20 -0.20 -0.20 -0.60
Out[22]:

(文)商品指数

In [3]:
pz = ['Wind橡胶指数','Wind商品指数','布油']
hc.bfb(df[pz])
Out[3]:

(慧)汇率

In [4]:
pz = ['Wind橡胶指数','美元指数','美元兑人民币(中间价)']
hc.y22(df[pz[:2]],addtype='corr')
hc.y22(df[pz[::2]],addtype='corr')
Out[4]:
Out[4]:

(姑)股市

In [5]:
pz = ['Wind橡胶指数','沪深300']
hc.y22(df[pz],addtype='corr')
Out[5]:

(周)季节性周期

In [6]:
pz='Wind橡胶指数'
# hc.season_bfb(df[pz],title=pz)
hc.season(df[pz],title=pz,ldic={13:[True,'square',4]},mondata=True)
# hc.season(df[pz],title=pz,ltype='column',mondata=True,showlst=[11,12,13])
Out[6]:

(日)日胶

In [7]:
pz = ['沪胶(活跃合约收盘)','日胶(活跃合约收盘)']
hc.bfb2(df[pz],addtype='corr')
Out[7]:

(正)政策冲击

In [8]:
pz=['Wind橡胶指数']
# ----获得事件数据-----
fpath ='./data/事件备忘.xlsx'
with open(fpath, "rb") as f:
    sjdf = pd.read_excel(f,sheet_name=[0,1],names=['x','kind','title','text','bz'],usecols=[0,1,2,3,4])
df0 = sjdf[0]
# df1 = sjdf[1]
df0 = df0[['x','title','text']][(df0.kind=='天胶') & (df0.title=='政')] # 根据事件涉及品种进行筛选
# df1 = df1[['x','title','text']][(df1.kind=='天胶') & (df1.bz=='单边')] 
df0 = df0.to_dict(orient='records')
# df1 = df1.to_dict(orient='records')
hc.y1(df[pz],sjdata=df0,sele=5)
Out[8]:

(差)比价分析

期现价差

In [9]:
hc.y2(df[['期现价差']],sele=5)
Out[9]:

从历史数据来看,期现价差核心波动区间分两个阶段:2013年前,在(-2000,2000);2013年开始在(0,2000)。如果背离该区间,向均值回归概率较大。

月间价差

In [10]:
pz = ['沪胶1月','沪胶5月','沪胶9月']
legend = ['1月-5月','5月-9月', '9月-1月']

df1 = df[pz[:2]].dropna()
df1[legend[0]] = df1[pz[0]]-df1[pz[1]] # 5月-1月
df1 = df1[df1.index.map(lambda t: t.month in [6,7,8,9,10,11,12])]

df2 = df[pz[1:]].dropna()
df2[legend[1]] = df2[pz[1]]-df2[pz[2]]  # 9月-5月
df2 = df2[df2.index.map(lambda t: t.month in [1,2,3,4,10,11,12])]

df3 = df[pz[::2]].dropna()
df3[legend[2]] = df3[pz[2]]-df3[pz[0]]  # 1月-9月
df3 = df3[df3.index.map(lambda t: t.month in [2,3,4,5,6,7,8])]

# # ----获得事件数据-----
# fpath ='./data/事件备忘.xlsx'
# with open(fpath, "rb") as f:
#     sjdf = pd.read_excel(f,sheet_name=[0,1],names=['x','kind','title','text','bz'],usecols=[0,1,2,3,4])
# df4 = sjdf[0]
# df5 = sjdf[1]
# df4 = df4[['x','title','text']][df4.kind=='郑煤'] # 根据事件涉及品种进行筛选
# df5 = df5[['x','title','text']][(df5.kind=='郑煤') & (df5.bz=='套利')] 
# df4 = df4.to_dict(orient='records')
# df5 = df5.to_dict(orient='records')
hc.y2(df1,y2list=[2],ldic={2:'column'})
Out[10]:
In [11]:
hc.y2(df2,y2list=[2],ldic={2:'column'})
Out[11]:
In [12]:
hc.y2(df3,y2list=[2],ldic={2:'column'})
Out[12]:

【说明】 基于流动性和对比一致性考虑,数据剔除了跨中间合约的月份数据,比如9-1只取2,3,4,5,6,7,8月的数据。

(供)供需情况

中国月度供需平衡

In [13]:
pz = ['Wind橡胶指数(月均)','天胶产量:中国','天胶进口:中国','天胶消费:中国', '月度供需差:中国']
mydf = df[pz].dropna(how='any')
# mydf[pz[4] + '同比'] = round((mydf[pz[4]] - mydf[pz[4]].shift(12)) / mydf[pz[4]].shift(12),2)
mydf.tail().fillna('')
pz1 = pz[2]
hc.season(mydf[pz1],title=pz1 + '(单位:千吨)',ltype='column',mondata=True,showlst=[8,9,10])
# hc.y22(mydf.iloc[:,[0,5]],sele=5,addtype='corr',cf=12)
hc.y2(mydf[pz[::4]],sele=5)
Out[13]:
Wind橡胶指数(月均) 天胶产量:中国 天胶进口:中国 天胶消费:中国 月度供需差:中国
2017-12-31 14246.44 38.00 685.50 447.00 276.50
2018-01-31 14053.97 0.60 543.40 450.00 94.00
2018-02-28 12902.27 0.00 286.10 384.00 -97.90
2018-03-31 12566.91 19.00 440.00 475.00 -16.00
2018-04-30 11626.66 55.00 434.20 470.00 19.20
Out[13]:
Out[13]:

ANRPC月度供应

In [14]:
pz = ['天胶产量:泰国','天胶产量:印尼','天胶产量:马来西亚', '天胶产量:越南','天胶产量:ANRPC']
mydf = df[pz].dropna(how='any')
mydf.tail().fillna('')
pz1 = '天胶产量:泰国'
hc.season(mydf[pz1],title=pz1 + '(单位:千吨)',ltype='column',mondata=True,showlst=[5,6,7])
Out[14]:
天胶产量:泰国 天胶产量:印尼 天胶产量:马来西亚 天胶产量:越南 天胶产量:ANRPC
2017-12-31 448.00 270.40 67.10 81.70 1028.70
2018-01-31 400.70 295.00 55.00 110.00 965.20
2018-02-28 455.40 298.10 63.20 50.00 939.70
2018-03-31 136.30 326.60 57.00 60.00 653.80
2018-04-30 292.60 354.70 44.00 80.00 902.20
Out[14]:
In [15]:
pz = ['天胶出口:泰国','天胶出口:印尼','天胶出口:马来西亚', '天胶出口:越南','天胶出口:ANRPC']
mydf = df[pz].dropna(how='any')
mydf.tail().fillna('')
pz1 = '天胶出口:泰国'
hc.season(mydf[pz1],title=pz1 + '(单位:千吨)',ltype='column',mondata=True,showlst=[5,6,7])
Out[15]:
天胶出口:泰国 天胶出口:印尼 天胶出口:马来西亚 天胶出口:越南 天胶出口:ANRPC
2017-12-31 478.80 241.90 110.00 169.30 1047.00
2018-01-31 256.20 230.00 87.20 135.30 748.00
2018-02-28 229.90 220.40 89.30 50.20 615.00
2018-03-31 177.10 270.70 100.80 76.10 661.00
2018-04-30 397.00 278.80 98.00 70.00 873.00
Out[15]:

国内显性库存

In [16]:
pz = ['青岛保税区橡胶库存','上期所天胶库存']
mydf = df[pz].dropna(how = 'any')
mydf.tail().fillna('')
pz1 = '青岛保税区橡胶库存'
hc.season(mydf[pz1],title = pz1 + '(单位:万吨)',showlst = [6,7,8])
Out[16]:
青岛保税区橡胶库存 上期所天胶库存
2018-04-03 22.65 41.79
2018-04-16 20.49 42.37
2018-05-02 18.34 42.76
2018-05-16 17.25 43.32
2018-06-05 17.52 44.61
Out[16]:

重卡销量

In [17]:
pz = ['Wind橡胶指数(月均)','重卡销量']
mydf = df[pz].dropna()
mydf[pz[1] + '同比'] = round((mydf[pz[1]] - mydf[pz[1]].shift(12)) / mydf[pz[1]].shift(12),2)
hc.y22(mydf.iloc[:,[0,2]],sele=5,addtype='corr',cf=12)
Out[17]:

(气)天气冲击

In [18]:
pz=['Wind橡胶指数']
# ----获得事件数据-----
fpath ='./data/事件备忘.xlsx'
with open(fpath, "rb") as f:
    sjdf = pd.read_excel(f,sheet_name=[0,1],names=['x','kind','title','text','bz'],usecols=[0,1,2,3,4])
df0 = sjdf[0]
# df1 = sjdf[1]
df0 = df0[['x','title','text']][(df0.kind=='天胶') & (df0.title=='气')]  # 根据事件涉及品种进行筛选
# df1 = df1[['x','title','text']][(df1.kind=='天胶') & (df1.bz=='单边')] 
df0 = df0.to_dict(orient='records')
# df1 = df1.to_dict(orient='records')
hc.y1(df[pz],sjdata=df0,sele=5)
Out[18]:

(袋)替代品

与复合橡胶相关分析

In [19]:
# 基本参数设置
label1='沪胶(活跃合约收盘)'
label2='顺丁橡胶(中石化华北)'
label3='丁苯橡胶(中石化华北)'
label4='丁二烯(中石化华北)'
legend = ['沪胶-顺丁','沪胶-丁苯','沪胶-丁二烯']
mydf = df[[label1,label2,label3,label4]]

# 叠加图
hc.bfb(mydf,sele=4)
mydf = mydf.dropna(how='any')

# 相关分析
df1 = mydf[label1]
df2 = mydf[label2]
df3 = mydf[label3]
df4 = mydf[label4]
z1 = df1.rolling(window=252).corr(other=df2)
z2 = df1.rolling(window=252).corr(other=df3)
z3 = df1.rolling(window=252).corr(other=df4)
mydf = pd.concat([z1, z2,z3], axis=1, join='inner')
mydf.columns=legend
hc.y2(mydf,y2list=[],sele=4)
Out[19]:
Out[19]:

沪胶与顺丁、丁苯价差跟踪

In [20]:
# 基本参数设置
label1='沪胶(活跃合约收盘)'
label2='顺丁橡胶(中石化华北)'
label3='丁苯橡胶(中石化华北)'
legend = ['沪胶-顺丁','沪胶-丁苯','沪胶']

# 数据清洗
df1 = df[label1] - df[label2]
df2 = df[label1] - df[label3]
df3 = df[label1]

mydf = pd.concat([df1, df2,df3], axis=1, join='inner')
mydf.columns = legend
hc.y2(mydf,y2list=[2],sele=4)
Out[20]:

相关股票表现

In [21]:
pz = ['Wind橡胶指数','中化国际','海南橡胶']
hc.bfb(df[pz])
Out[21]: